home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / MDB2 / Extended.php < prev    next >
Encoding:
PHP Script  |  2006-04-07  |  21.2 KB  |  598 lines

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP versions 4 and 5                                                 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
  6. // | Stig. S. Bakken, Lukas Smith                                         |
  7. // | All rights reserved.                                                 |
  8. // +----------------------------------------------------------------------+
  9. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  10. // | API as well as database abstraction for PHP applications.            |
  11. // | This LICENSE is in the BSD license style.                            |
  12. // |                                                                      |
  13. // | Redistribution and use in source and binary forms, with or without   |
  14. // | modification, are permitted provided that the following conditions   |
  15. // | are met:                                                             |
  16. // |                                                                      |
  17. // | Redistributions of source code must retain the above copyright       |
  18. // | notice, this list of conditions and the following disclaimer.        |
  19. // |                                                                      |
  20. // | Redistributions in binary form must reproduce the above copyright    |
  21. // | notice, this list of conditions and the following disclaimer in the  |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // |                                                                      |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission.                                                  |
  28. // |                                                                      |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@pooteeweet.org>                           |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: Extended.php,v 1.36 2006/02/09 12:45:30 lsmith Exp $
  46.  
  47. /**
  48.  * @package  MDB2
  49.  * @category Database
  50.  * @author   Lukas Smith <smith@pooteeweet.org>
  51.  */
  52.  
  53. /**
  54.  * Used by autoPrepare()
  55.  */
  56. define('MDB2_AUTOQUERY_INSERT', 1);
  57. define('MDB2_AUTOQUERY_UPDATE', 2);
  58.  
  59. /**
  60.  * MDB2_Extended: class which adds several high level methods to MDB2
  61.  *
  62.  * @package MDB2
  63.  * @category Database
  64.  * @author Lukas Smith <smith@pooteeweet.org>
  65.  */
  66. class MDB2_Extended extends MDB2_Module_Common
  67. {
  68.     // {{{ autoPrepare()
  69.  
  70.     /**
  71.      * Make automaticaly an insert or update query and call prepare() with it
  72.      *
  73.      * @param string table
  74.      * @param array the fields names
  75.      * @param int type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
  76.      * @param string (in case of update queries, this string will be put after the sql WHERE statement)
  77.      * @param array that contains the types of the placeholders
  78.      *
  79.      * @return resource handle for the query
  80.      * @see buildManipSQL
  81.      * @access public
  82.      */
  83.     function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT,
  84.         $where = false, $types = null)
  85.     {
  86.         $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
  87.         if (PEAR::isError($query)) {
  88.             return $query;
  89.         }
  90.         $db =& $this->getDBInstance();
  91.         if (PEAR::isError($db)) {
  92.             return $db;
  93.         }
  94.  
  95.         return $db->prepare($query, $types, false);
  96.     }
  97.     // }}}
  98.  
  99.     // {{{ autoExecute()
  100.  
  101.     /**
  102.      * Make automaticaly an insert or update query and call prepare() and execute() with it
  103.      *
  104.      * @param string name of the table
  105.      * @param array assoc ($key=>$value) where $key is a field name and $value its value
  106.      * @param int type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
  107.      * @param string (in case of update queries, this string will be put after the sql WHERE statement)
  108.      * @param array that contains the types of the placeholders
  109.      * @param string which specifies which result class to use
  110.      *
  111.      * @return bool|MDB2_Error true on success, a MDB2 error on failure
  112.      * @see buildManipSQL
  113.      * @see autoPrepare
  114.      * @access public
  115.     */
  116.     function &autoExecute($table, $fields_values, $mode = MDB2_AUTOQUERY_INSERT,
  117.         $where = false, $types = null, $result_class = true)
  118.     {
  119.         $stmt = $this->autoPrepare($table, array_keys($fields_values), $mode, $where, $types);
  120.         if (PEAR::isError($stmt)) {
  121.             return $stmt;
  122.         }
  123.         $params = array_values($fields_values);
  124.         $result =& $stmt->execute($params, $result_class);
  125.         $stmt->free();
  126.         return $result;
  127.     }
  128.     // }}}
  129.  
  130.     // {{{ buildManipSQL()
  131.  
  132.     /**
  133.      * Make automaticaly an sql query for prepare()
  134.      *
  135.      * Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), MDB2_AUTOQUERY_INSERT)
  136.      *           will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
  137.      * NB : - This belongs more to a SQL Builder class, but this is a simple facility
  138.      *      - Be carefull ! If you don't give a $where param with an UPDATE query, all
  139.      *        the records of the table will be updated !
  140.      *
  141.      * @param string name of the table
  142.      * @param ordered array containing the fields names
  143.      * @param int type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
  144.      * @param string (in case of update queries, this string will be put after the sql WHERE statement)
  145.      *
  146.      * @return string sql query for prepare()
  147.      * @access public
  148.      */
  149.     function buildManipSQL($table, $table_fields, $mode, $where = false)
  150.     {
  151.         $db =& $this->getDBInstance();
  152.         if (PEAR::isError($db)) {
  153.             return $db;
  154.         }
  155.  
  156.         if (count($table_fields) == 0) {
  157.             return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
  158.         }
  159.         switch ($mode) {
  160.         case MDB2_AUTOQUERY_INSERT:
  161.             $cols = implode(', ', $table_fields);
  162.             $values = '?'.str_repeat(', ?', count($table_fields)-1);
  163.             return 'INSERT INTO '.$table.' ('.$cols.') VALUES ('.$values.')';
  164.             break;
  165.         case MDB2_AUTOQUERY_UPDATE:
  166.             $set = implode(' = ?, ', $table_fields).' = ?';
  167.             $sql = 'UPDATE '.$table.' SET '.$set;
  168.             if ($where !== false) {
  169.                 $sql.= ' WHERE '.$where;
  170.             }
  171.             return $sql;
  172.             break;
  173.         }
  174.         return $db->raiseError(MDB2_ERROR_SYNTAX);
  175.     }
  176.     // }}}
  177.  
  178.     // {{{ limitQuery()
  179.  
  180.     /**
  181.      * Generates a limited query
  182.      *
  183.      * @param string query
  184.      * @param array that contains the types of the columns in the result set
  185.      * @param integer the row to start to fetching
  186.      * @param integer the numbers of rows to fetch
  187.      * @param string which specifies which result class to use
  188.      *
  189.      * @return MDB2_Result|MDB2_Error result set on success, a MDB2 error on failure
  190.      * @access public
  191.      */
  192.     function &limitQuery($query, $types, $count, $from = 0, $result_class = true)
  193.     {
  194.         $db =& $this->getDBInstance();
  195.         if (PEAR::isError($db)) {
  196.             return $db;
  197.         }
  198.  
  199.         $result = $db->setLimit($count, $from);
  200.         if (PEAR::isError($result)) {
  201.             return $result;
  202.         }
  203.         $result =& $db->query($query, $types, $result_class);
  204.         return $result;
  205.     }
  206.     // }}}
  207.  
  208.     // {{{ getOne()
  209.  
  210.     /**
  211.      * Fetch the first column of the first row of data returned from a query.
  212.      * Takes care of doing the query and freeing the results when finished.
  213.      *
  214.      * @param string the SQL query
  215.      * @param string that contains the type of the column in the result set
  216.      * @param array if supplied, prepare/execute will be used
  217.      *       with this array as execute parameters
  218.      * @param array that contains the types of the values defined in $params
  219.      * @param int|string which column to return
  220.      *
  221.      * @return scalar|MDB2_Error data on success, a MDB2 error on failure
  222.      * @access public
  223.      */
  224.     function getOne($query, $type = null, $params = array(),
  225.         $param_types = null, $colnum = 0)
  226.     {
  227.         $db =& $this->getDBInstance();
  228.         if (PEAR::isError($db)) {
  229.             return $db;
  230.         }
  231.  
  232.         settype($params, 'array');
  233.         settype($type, 'array');
  234.         if (count($params) == 0) {
  235.             return $db->queryOne($query, $type, $colnum);
  236.         }
  237.  
  238.         $stmt = $db->prepare($query, $param_types, $type);
  239.         if (PEAR::isError($stmt)) {
  240.             return $stmt;
  241.         }
  242.  
  243.         $stmt->bindParamArray($params);
  244.         $result = $stmt->execute();
  245.         if (!MDB2::isResultCommon($result)) {
  246.             return $result;
  247.         }
  248.  
  249.         $one = $result->fetchOne($colnum);
  250.         $stmt->free();
  251.         $result->free();
  252.         return $one;
  253.     }
  254.     // }}}
  255.  
  256.     // {{{ getRow()
  257.  
  258.     /**
  259.      * Fetch the first row of data returned from a query.  Takes care
  260.      * of doing the query and freeing the results when finished.
  261.      *
  262.      * @param string the SQL query
  263.      * @param array that contains the types of the columns in the result set
  264.      * @param array if supplied, prepare/execute will be used
  265.      *       with this array as execute parameters
  266.      * @param array that contains the types of the values defined in $params
  267.      * @param int the fetch mode to use
  268.      *
  269.      * @return array|MDB2_Error data on success, a MDB2 error on failure
  270.      * @access public
  271.      */
  272.     function getRow($query, $types = null, $params = array(),
  273.         $param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT)
  274.     {
  275.         $db =& $this->getDBInstance();
  276.         if (PEAR::isError($db)) {
  277.             return $db;
  278.         }
  279.  
  280.         settype($params, 'array');
  281.         if (count($params) == 0) {
  282.             return $db->queryRow($query, $types, $fetchmode);
  283.         }
  284.  
  285.         $stmt = $db->prepare($query, $param_types, $types);
  286.         if (PEAR::isError($stmt)) {
  287.             return $stmt;
  288.         }
  289.  
  290.         $stmt->bindParamArray($params);
  291.         $result = $stmt->execute();
  292.         if (!MDB2::isResultCommon($result)) {
  293.             return $result;
  294.         }
  295.  
  296.         $row = $result->fetchRow($fetchmode);
  297.         $stmt->free();
  298.         $result->free();
  299.         return $row;
  300.     }
  301.     // }}}
  302.  
  303.     // {{{ getCol()
  304.  
  305.     /**
  306.      * Fetch a single column from a result set and return it as an
  307.      * indexed array.
  308.      *
  309.      * @param string the SQL query
  310.      * @param string that contains the type of the column in the result set
  311.      * @param array if supplied, prepare/execute will be used
  312.      *       with this array as execute parameters
  313.      * @param array that contains the types of the values defined in $params
  314.      * @param int|string which column to return
  315.      *
  316.      * @return array|MDB2_Error data on success, a MDB2 error on failure
  317.      * @access public
  318.      */
  319.     function getCol($query, $type = null, $params = array(),
  320.         $param_types = null, $colnum = 0)
  321.     {
  322.         $db =& $this->getDBInstance();
  323.         if (PEAR::isError($db)) {
  324.             return $db;
  325.         }
  326.  
  327.         settype($params, 'array');
  328.         settype($type, 'array');
  329.         if (count($params) == 0) {
  330.             return $db->queryCol($query, $type, $colnum);
  331.         }
  332.  
  333.         $stmt = $db->prepare($query, $param_types, $type);
  334.         if (PEAR::isError($stmt)) {
  335.             return $stmt;
  336.         }
  337.  
  338.         $stmt->bindParamArray($params);
  339.         $result = $stmt->execute();
  340.         if (!MDB2::isResultCommon($result)) {
  341.             return $result;
  342.         }
  343.  
  344.         $col = $result->fetchCol($colnum);
  345.         $stmt->free();
  346.         $result->free();
  347.         return $col;
  348.     }
  349.     // }}}
  350.  
  351.     // {{{ getAll()
  352.  
  353.     /**
  354.      * Fetch all the rows returned from a query.
  355.      *
  356.      * @param string the SQL query
  357.      * @param array that contains the types of the columns in the result set
  358.      * @param array if supplied, prepare/execute will be used
  359.      *       with this array as execute parameters
  360.      * @param array that contains the types of the values defined in $params
  361.      * @param int the fetch mode to use
  362.      * @param bool if set to true, the $all will have the first
  363.      *       column as its first dimension
  364.      * @param bool $force_array used only when the query returns exactly
  365.      *       two columns. If true, the values of the returned array will be
  366.      *       one-element arrays instead of scalars.
  367.      * @param bool $group if true, the values of the returned array is
  368.      *       wrapped in another array.  If the same key value (in the first
  369.      *       column) repeats itself, the values will be appended to this array
  370.      *       instead of overwriting the existing values.
  371.      *
  372.      * @return array|MDB2_Error data on success, a MDB2 error on failure
  373.      * @access public
  374.      */
  375.     function getAll($query, $types = null, $params = array(),
  376.         $param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT,
  377.         $rekey = false, $force_array = false, $group = false)
  378.     {
  379.         $db =& $this->getDBInstance();
  380.         if (PEAR::isError($db)) {
  381.             return $db;
  382.         }
  383.  
  384.         settype($params, 'array');
  385.         if (count($params) == 0) {
  386.             return $db->queryAll($query, $types, $fetchmode, $rekey, $force_array, $group);
  387.         }
  388.  
  389.         $stmt = $db->prepare($query, $param_types, $types);
  390.         if (PEAR::isError($stmt)) {
  391.             return $stmt;
  392.         }
  393.  
  394.         $stmt->bindParamArray($params);
  395.         $result = $stmt->execute();
  396.         if (!MDB2::isResultCommon($result)) {
  397.             return $result;
  398.         }
  399.  
  400.         $all = $result->fetchAll($fetchmode, $rekey, $force_array, $group);
  401.         $stmt->free();
  402.         $result->free();
  403.         return $all;
  404.     }
  405.     // }}}
  406.  
  407.     // {{{ getAssoc()
  408.  
  409.     /**
  410.      * Fetch the entire result set of a query and return it as an
  411.      * associative array using the first column as the key.
  412.      *
  413.      * If the result set contains more than two columns, the value
  414.      * will be an array of the values from column 2-n.  If the result
  415.      * set contains only two columns, the returned value will be a
  416.      * scalar with the value of the second column (unless forced to an
  417.      * array with the $force_array parameter).  A MDB2 error code is
  418.      * returned on errors.  If the result set contains fewer than two
  419.      * columns, a MDB2_ERROR_TRUNCATED error is returned.
  420.      *
  421.      * For example, if the table 'mytable' contains:
  422.      *
  423.      *   ID      TEXT       DATE
  424.      * --------------------------------
  425.      *   1       'one'      944679408
  426.      *   2       'two'      944679408
  427.      *   3       'three'    944679408
  428.      *
  429.      * Then the call getAssoc('SELECT id,text FROM mytable') returns:
  430.      *    array(
  431.      *      '1' => 'one',
  432.      *      '2' => 'two',
  433.      *      '3' => 'three',
  434.      *    )
  435.      *
  436.      * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
  437.      *    array(
  438.      *      '1' => array('one', '944679408'),
  439.      *      '2' => array('two', '944679408'),
  440.      *      '3' => array('three', '944679408')
  441.      *    )
  442.      *
  443.      * If the more than one row occurs with the same value in the
  444.      * first column, the last row overwrites all previous ones by
  445.      * default.  Use the $group parameter if you don't want to
  446.      * overwrite like this.  Example:
  447.      *
  448.      * getAssoc('SELECT category,id,name FROM mytable', null, null
  449.      *           MDB2_FETCHMODE_ASSOC, false, true) returns:
  450.      *    array(
  451.      *      '1' => array(array('id' => '4', 'name' => 'number four'),
  452.      *                   array('id' => '6', 'name' => 'number six')
  453.      *             ),
  454.      *      '9' => array(array('id' => '4', 'name' => 'number four'),
  455.      *                   array('id' => '6', 'name' => 'number six')
  456.      *             )
  457.      *    )
  458.      *
  459.      * Keep in mind that database functions in PHP usually return string
  460.      * values for results regardless of the database's internal type.
  461.      *
  462.      * @param string the SQL query
  463.      * @param array that contains the types of the columns in the result set
  464.      * @param array if supplied, prepare/execute will be used
  465.      *       with this array as execute parameters
  466.      * @param array that contains the types of the values defined in $params
  467.      * @param bool $force_array used only when the query returns
  468.      * exactly two columns.  If TRUE, the values of the returned array
  469.      * will be one-element arrays instead of scalars.
  470.      * @param bool $group if TRUE, the values of the returned array
  471.      *       is wrapped in another array.  If the same key value (in the first
  472.      *       column) repeats itself, the values will be appended to this array
  473.      *       instead of overwriting the existing values.
  474.      *
  475.      * @return array|MDB2_Error data on success, a MDB2 error on failure
  476.      * @access public
  477.      */
  478.     function getAssoc($query, $types = null, $params = array(), $param_types = null,
  479.         $fetchmode = MDB2_FETCHMODE_DEFAULT, $force_array = false, $group = false)
  480.     {
  481.         $db =& $this->getDBInstance();
  482.         if (PEAR::isError($db)) {
  483.             return $db;
  484.         }
  485.  
  486.         settype($params, 'array');
  487.         if (count($params) == 0) {
  488.             return $db->queryAll($query, $types, $fetchmode, true, $force_array, $group);
  489.         }
  490.  
  491.         $stmt = $db->prepare($query, $param_types, $types);
  492.         if (PEAR::isError($stmt)) {
  493.             return $stmt;
  494.         }
  495.  
  496.         $stmt->bindParamArray($params);
  497.         $result = $stmt->execute();
  498.         if (!MDB2::isResultCommon($result)) {
  499.             return $result;
  500.         }
  501.  
  502.         $all = $result->fetchAll($fetchmode, true, $force_array, $group);
  503.         $stmt->free();
  504.         $result->free();
  505.         return $all;
  506.     }
  507.     // }}}
  508.  
  509.     // {{{ executeMultiple()
  510.  
  511.     /**
  512.      * This function does several execute() calls on the same statement handle.
  513.      * $params must be an array indexed numerically from 0, one execute call is
  514.      * done for every 'row' in the array.
  515.      *
  516.      * If an error occurs during execute(), executeMultiple() does not execute
  517.      * the unfinished rows, but rather returns that error.
  518.      *
  519.      * @param resource query handle from prepare()
  520.      * @param array numeric array containing the data to insert into the query
  521.      *
  522.      * @return bool|MDB2_Error true on success, a MDB2 error on failure
  523.      * @access public
  524.      * @see prepare(), execute()
  525.      */
  526.     function executeMultiple(&$stmt, $params = null)
  527.     {
  528.         for ($i = 0, $j = count($params); $i < $j; $i++) {
  529.             $stmt->bindParamArray($params[$i]);
  530.             $result = $stmt->execute();
  531.             if (PEAR::isError($result)) {
  532.                 return $result;
  533.             }
  534.         }
  535.         return MDB2_OK;
  536.     }
  537.     // }}}
  538.  
  539.     // {{{ getBeforeID()
  540.  
  541.     /**
  542.      * returns the next free id of a sequence if the RDBMS
  543.      * does not support auto increment
  544.      *
  545.      * @param string name of the table into which a new row was inserted
  546.      * @param string name of the field into which a new row was inserted
  547.      * @param bool when true the sequence is automatic created, if it not exists
  548.      *
  549.      * @return int|MDB2_Error id on success, a MDB2 error on failure
  550.      * @access public
  551.      */
  552.     function getBeforeID($table, $field = null, $ondemand = true)
  553.     {
  554.         $db =& $this->getDBInstance();
  555.         if (PEAR::isError($db)) {
  556.             return $db;
  557.         }
  558.  
  559.         if ($db->supports('auto_increment') !== true) {
  560.             $seq = $table.(empty($field) ? '' : '_'.$field);
  561.             $id = $db->nextID($seq, $ondemand);
  562.             if (PEAR::isError($id)) {
  563.                 return $id;
  564.             }
  565.             return $db->quote($id, 'integer');
  566.         }
  567.         return 'NULL';
  568.     }
  569.     // }}}
  570.  
  571.     // {{{ getAfterID()
  572.  
  573.     /**
  574.      * returns the autoincrement ID if supported or $id
  575.      *
  576.      * @param mixed value as returned by getBeforeId()
  577.      * @param string name of the table into which a new row was inserted
  578.      * @param string name of the field into which a new row was inserted
  579.      *
  580.      * @return int|MDB2_Error id on success, a MDB2 error on failure
  581.      * @access public
  582.      */
  583.     function getAfterID($id, $table, $field = null)
  584.     {
  585.         $db =& $this->getDBInstance();
  586.         if (PEAR::isError($db)) {
  587.             return $db;
  588.         }
  589.  
  590.         if ($db->supports('auto_increment') !== true) {
  591.             return $id;
  592.         }
  593.         return $db->lastInsertID($table, $field);
  594.     }
  595.     // }}}
  596. }
  597. ?>
  598.